package com.alibaba.citrus.ots.forecast.facade.service;

import com.alibaba.citrus.ots.common.exception.FacadeException;
import com.alibaba.citrus.ots.common.exception.FunctionException;
import com.alibaba.citrus.ots.common.model.ApiContext;
import com.alibaba.citrus.ots.forecast.functions.forecastorder.constants.ForecastConstants;
import com.alibaba.citrus.ots.forecast.functions.forecastorder.entity.ForecastOrderEntity;
import com.alibaba.citrus.ots.forecast.functions.forecastorder.factory.ForecastOrderFactory;
import com.alibaba.citrus.ots.forecast.repository.ForecastOrderLineQueryRepository;
import com.alibaba.citrus.ots.forecast.repository.ForecastOrderLineWriteRepository;
import com.alibaba.citrus.ots.forecast.repository.ForecastOrderWriteRepository;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.epoch.app.bcots.platform_enhance.SaleOrderTag;
import com.epoch.app.otsforecastsales.dto.request.ConfirmForecastRequest;
import com.epoch.app.otsforecastsales.model.dto.ActivitySDO;
import com.epoch.app.otsforecastsales.model.dto.FailOrderRequest;
import com.epoch.app.otsforecastsales.model.enums.ForecastDealStatusSEO;
import com.epoch.app.otsforecastsales.sdo.ForecastOrderLineSDO;
import com.epoch.app.otsforecastsales.sdo.ForecastOrderSDO;
import com.epoch.app.otspricecenter.api.activitywrite.service.ActivityWriteService;
import com.epoch.app.otspricecenter.dto.request.ActivityInfoRequest;
import com.epoch.app.otspricecenter.dto.request.ActivityItemInfo;
import com.epoch.app.otspricecenter.dto.request.CoverActivityInfoRequest;
import com.epoch.app.otspricecenter.dto.request.CoverActivityTermRequest;
import com.epoch.app.otspricecenter.dto.response.CoverInActivityResponse;
import com.epoch.app.otspricecenter.model.dto.CoverActivityRequest;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: jinghang
 * @Date: 2021/12/15
 * @Description:
 */
@Component
public class FailOrderProcessor {

    private static final Log log = Log.getLogger(FailOrderProcessor.class);


    private static final String CODE_FLAG = "codeFlag";

    /**
     * 内外码转换 value
     */
    private static final String INNER_CODE_TO_OUT_CODE = "inner_code_to_out_code";

    @Autowired
    private ActivityWriteService activityWriteService;

    @Autowired
    private ForecastOrderLineWriteRepository forecastOrderLineWriteRepository;

    @Autowired
    private ForecastOrderLineQueryRepository forecastOrderLineQueryRepository;

    @Autowired
    private ForecastOrderWriteRepository forecastOrderWriteRepository;


    public void process(String message, ApiContext apiContext){
        if (StringUtils.isEmpty(message)){
            return;
        }
        FailOrderRequest request = JSON.parseObject(message, FailOrderRequest.class);
        ConfirmForecastRequest confirmForecastRequest = new ConfirmForecastRequest();
        confirmForecastRequest.setIds(request.getFailOrderIds());
        String sequenceNo = request.getSequenceNo();
        List<ForecastOrderEntity> forecastOrderEntities = ForecastOrderFactory.confrimForecast(confirmForecastRequest);

        if (CollectionUtils.isEmpty(forecastOrderEntities) || forecastOrderEntities.size() > 1){
            log.warn("main order is null or main order size > 1, subIds={}",request.getFailOrderIds());
            // 为空或者对应的不止一个预报主单则直接返回
            return;
        }

        ForecastOrderEntity forecastOrderEntity = forecastOrderEntities.get(0);


        if (CollectionUtils.isEmpty(forecastOrderEntity.getForecastOrderSDO().getForecastOrderLineSDOList())){
            log.warn("sub order lines is null, ids={}",request.getFailOrderIds());
            return;
        }

        /*boolean checkStatus = forecastOrderEntity.getForecastOrderSDO().getForecastOrderLineSDOList()
                .stream()
                .anyMatch(orderLine -> !ForecastDealStatusSEO.CONFIRM_ING.getStatus().equals(orderLine.getDealStatus()));
        if (checkStatus){
            log.warn("sub order lines status is not CONFIRM_ING, ids={}",request.getFailOrderIds());
            return;
        }*/

        recoverActivity(forecastOrderEntity, apiContext, sequenceNo);

        recoverForecastOrder(forecastOrderEntity, apiContext);

    }

    private void recoverActivity(ForecastOrderEntity forecastOrderEntity, ApiContext apiContext, String sequenceNo){

        if (StringUtils.isEmpty(sequenceNo)){
            return;
        }

        CoverActivityRequest coverActivityRequest = new CoverActivityRequest();
        List<CoverActivityInfoRequest> coverActivityInfoRequests = new ArrayList<>();
        coverActivityRequest.setCoverActivityInfoList(coverActivityInfoRequests);
        ForecastOrderSDO forecastOrderSDO = forecastOrderEntity.getForecastOrderSDO();
        for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
            Map features = forecastOrderLineSDO.getFeatures();
            if (MapUtils.isEmpty(features) || StringUtils.isEmpty(forecastOrderLineSDO.getActivityCode())){
                continue;
            }
            //判断子订单是否需要经过活动检查
                //添加活动参数
            List<ActivitySDO> activitySDOS = new ArrayList<>();
            if (Objects.nonNull(features.get(ForecastConstants.ACTIVITY_DETAILS))) {
                activitySDOS = JSONObject.parseArray(JSON.toJSONString(features.get(ForecastConstants.ACTIVITY_DETAILS)), ActivitySDO.class);
            }

            //补货活动单独处理
            if (SaleOrderTag.REPLENISH_FORECAST.getCode().equals(forecastOrderSDO.getOrderType())
                    && CollectionUtils.isEmpty(activitySDOS)) {
                activitySDOS = new ArrayList<>();
                ActivitySDO activitySDO = new ActivitySDO();
                activitySDO.setActivityCode(forecastOrderLineSDO.getActivityCode());
                activitySDO.setActivityTermid(features.get(ForecastConstants.ACTIVITY_NUMBER).toString());
                activitySDO.setIsSelect(true);
                activitySDOS.add(activitySDO);
            }

            for (ActivitySDO activitySDO : activitySDOS) {
                if (Objects.isNull(activitySDO)
                        || Objects.isNull(activitySDO.getIsSelect())
                        || !activitySDO.getIsSelect()) {
                    continue;
                }

                //回滚活动的入参
                CoverActivityInfoRequest coverActivityInfoRequest = buildCoverActivityInfoRequest(forecastOrderSDO, forecastOrderLineSDO, activitySDO, sequenceNo);
                coverActivityInfoRequests.add(coverActivityInfoRequest);
            }
        }
        if (CollectionUtils.isNotEmpty(coverActivityRequest.getCoverActivityInfoList())) {
            Map<String, String> activityFeatures = new HashMap<>();
            activityFeatures.put(CODE_FLAG, INNER_CODE_TO_OUT_CODE);
            coverActivityRequest.setFeatures(activityFeatures);
            Result<CoverInActivityResponse> coverInActivityResponseResult = activityWriteService.activityCoverExpand(coverActivityRequest);
            if (!coverInActivityResponseResult.isSuccess()) {
                log.error("FailOrderProcessor$recoverActivity_fail");
                throw new FacadeException("back activity error, OrderId=" + forecastOrderEntity.getForecastOrderSDO().getId());
            }
        }

    }

    private void recoverForecastOrder(ForecastOrderEntity forecastOrderEntity, ApiContext apiContext){
            ForecastOrderSDO forecastOrderSDO = forecastOrderEntity.getForecastOrderSDO();
            for (ForecastOrderLineSDO forecastOrderLineSDO : forecastOrderSDO.getForecastOrderLineSDOList()) {
                // 回补预报单
                // 是确认中状态  回滚
                if (ForecastDealStatusSEO.CONFIRM_ING.getStatus().equals(forecastOrderLineSDO.getDealStatus())){
                    forecastOrderLineSDO.setDealStatus(ForecastDealStatusSEO.WAITING_DEAL.getStatus());
                    if (apiContext != null){
                        forecastOrderLineSDO.setModifierId(apiContext.getEmployeeId());
                        forecastOrderLineSDO.setModifierName(apiContext.getEmployeeName());
                    }
                    forecastOrderLineSDO.setGmtModified(new Date());
                    Boolean result = forecastOrderLineWriteRepository.submit(forecastOrderLineSDO);
                    if (!result) {
                        log.error("FailOrderProcessor$recoverForecastOrder_fail");
                        throw new FacadeException("modify order line status error, Id=" + forecastOrderLineSDO.getId());
                    }
                }
            }
    }

    private CoverActivityInfoRequest buildCoverActivityInfoRequest(ForecastOrderSDO forecastOrderSDO, ForecastOrderLineSDO forecastOrderLineSDO, ActivitySDO activitySDO, String sequenceNo) {
        CoverActivityInfoRequest coverActivityInfoRequest = new CoverActivityInfoRequest();
        coverActivityInfoRequest.setActivityId(activitySDO.getActivityCode());
        coverActivityInfoRequest.setClientId(forecastOrderSDO.getCustomerCode());
        coverActivityInfoRequest.setMainOrderId(forecastOrderLineSDO.getMainOrderId());
        coverActivityInfoRequest.setSubOrderId(String.valueOf(forecastOrderLineSDO.getId()));
        coverActivityInfoRequest.setOrderType(forecastOrderSDO.getOrderType());
        coverActivityInfoRequest.setDeliveryDate(forecastOrderSDO.getCustomerExpectTDate());
        coverActivityInfoRequest.setActivityUseTime(new Date());
        coverActivityInfoRequest.setSequenceNo(sequenceNo);
        CoverActivityTermRequest coverActivityTermRequest = new CoverActivityTermRequest();
        coverActivityTermRequest.setActivityTermId(activitySDO.getActivityTermid());
        coverActivityTermRequest.setSpecialOfferPrice(activitySDO.getSpecialOfferPrice());


        //原品信息
        ActivityItemInfo itemActivityItemInfo = new ActivityItemInfo();
        itemActivityItemInfo.setItemId(forecastOrderLineSDO.getScItemId());
        Integer itemQuantity = forecastOrderLineSDO.getPredictReplyAmount() == null ? Integer.parseInt(forecastOrderLineSDO.getQuantity()) :
                forecastOrderLineSDO.getPredictReplyAmount();
        itemActivityItemInfo.setItemQuantity(itemQuantity);
        itemActivityItemInfo.setItemName(forecastOrderLineSDO.getScItemTitle());
        itemActivityItemInfo.setItemPrice(Long.parseLong(String.valueOf(forecastOrderLineSDO.getUnitPrice() == null ? "0" : forecastOrderLineSDO.getUnitPrice())));
        itemActivityItemInfo.setSalesUnit(forecastOrderLineSDO.getSaleUnit());
        itemActivityItemInfo.setStockUnit(forecastOrderLineSDO.getInventoryUnit());
        coverActivityTermRequest.setItem(itemActivityItemInfo);
        coverActivityTermRequest.setVersion(activitySDO.getVersion());

        //赠品信息
        List<ActivityItemInfo> giftList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(activitySDO.getChooseGiftList())) {
            activitySDO.getChooseGiftList().forEach(giftSDO -> {
                ActivityItemInfo activityItemInfo = new ActivityItemInfo();
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                activityItemInfo.setItemId(giftSDO.getScItemId());
                activityItemInfo.setItemName(giftSDO.getGiftName());
                activityItemInfo.setItemQuantity(giftSDO.getGiftNumber());
                activityItemInfo.setSalesUnit(giftSDO.getGiftUint());
                activityItemInfo.setItemPrice(giftSDO.getGiftPrice());
                giftList.add(activityItemInfo);
            });
        }

        coverActivityTermRequest.setGiftList(giftList);
        coverActivityInfoRequest.setCoverActivityTermRequest(coverActivityTermRequest);
        return coverActivityInfoRequest;
    }


}
